/* 注意：
 * 在使用 xstruct 宏时不要出现多余的逗号，像这样
 * xstruct(
 *     xname(foo),
 *     xprif(bar, type), <- 多余的逗号
 * )
 */

#ifndef xpack_macro_xstruct
#define xpack_macro_xstruct
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::macro_xstruct::inc
#include"define/classify.hpp"
#include"macro/private/xlist.hpp"
#include"macro/private/word.hpp"
#include"macro/private/xstruct.concept.hpp"
#include"macro/private/xstruct.inc.hpp"
#include"macro/private/xstruct.op.hpp"
#include"macro/private/xstruct.prop.hpp"
#include"macro/xmark+.hpp"
#include"macro/xoffsetof.hpp"
#pragma pop_macro("xuser")

namespace mixc::macro_xtypeid{
    template<class, class> struct __typeid;
}

namespace mixc::gc_private_gc_tuple{
    template<class> struct gc_tuple;
}

namespace mixc::macro_xtypeid{
    template<class, class> struct __typeid;
}

// 结构名
#define __xstruct__
#define __xstruct_name__(...)               __VA_ARGS__
#define __xstruct_tmpl__(NAME,...)          NAME
#define __xstruct_spec__(NAME,...)          NAME<__VA_ARGS__>
#define __xstruct_pubb__(...)
#define __xstruct_prob__(...)
#define __xstruct_prib__(...)
#define __xstruct_pubf__(...)
#define __xstruct_prof__(...)
#define __xstruct_prif__(...)
#define __xstruct_pubf_no_mut__(...)
#define __xstruct_prof_no_mut__(...)
#define __xstruct_prif_no_mut__(...)
#define __xstruct_pubc__(...)
#define __xstruct_proc__(...)
#define __xstruct_pric__(...)
#define __xstruct_asso__(...)
#define __xstruct_whos__(...)
#define __xstruct___declspec(...)           __declspec(__VA_ARGS__)
#define __xstruct___attribute__(...)        __attribute__(__VA_ARGS__)


// 基类
#define __xexpand_first__
#define __xexpand_first_name__(...)
#define __xexpand_first_tmpl__(...)
#define __xexpand_first_spec__(...)
#define __xexpand_first_pubb__(...)         : public      __VA_ARGS__ 
#define __xexpand_first_prob__(...)         : protected   __VA_ARGS__ 
#define __xexpand_first_prib__(...)         : private     __VA_ARGS__ 
#define __xexpand_first_pubf__(...)
#define __xexpand_first_prof__(...)
#define __xexpand_first_prif__(...)
#define __xexpand_first_pubf_no_mut__(...)
#define __xexpand_first_prof_no_mut__(...)
#define __xexpand_first_prif_no_mut__(...)
#define __xexpand_first_pubc__(...)
#define __xexpand_first_proc__(...)
#define __xexpand_first_pric__(...)
#define __xexpand_first_asso__(...)
#define __xexpand_first_whos__(...)
#define __xexpand_first___declspec(...)
#define __xexpand_first___attribute__(...)


// 基类
#define __xexpand__
#define __xexpand_name__(...)
#define __xexpand_tmpl__(...)
#define __xexpand_spec__(...)
#define __xexpand_pubb__(...)               , public      __VA_ARGS__
#define __xexpand_prob__(...)               , protected   __VA_ARGS__
#define __xexpand_prib__(...)               , private     __VA_ARGS__
#define __xexpand_pubf__(...)
#define __xexpand_prof__(...)
#define __xexpand_prif__(...)
#define __xexpand_pubf_no_mut__(...)
#define __xexpand_prof_no_mut__(...)
#define __xexpand_prif_no_mut__(...)
#define __xexpand_pubc__(...)
#define __xexpand_proc__(...)
#define __xexpand_pric__(...)
#define __xexpand_asso__(...)
#define __xexpand_whos__(...)
#define __xexpand___declspec(...)
#define __xexpand___attribute__(...)

// the_t 别名
#define __xthe__
#define __xthe_name__(...)                  __VA_ARGS__
#define __xthe_tmpl__(NAME,...)             NAME<__VA_ARGS__>
#define __xthe_spec__(NAME,...)             NAME<__VA_ARGS__>
#define __xthe_pubb__(...)
#define __xthe_prob__(...)
#define __xthe_prib__(...)
#define __xthe_pubf__(...)
#define __xthe_prof__(...)
#define __xthe_prif__(...)
#define __xthe_pubf_no_mut__(...)
#define __xthe_prof_no_mut__(...)
#define __xthe_prif_no_mut__(...)
#define __xthe_pubc__(...)
#define __xthe_proc__(...)
#define __xthe_pric__(...)
#define __xthe_asso__(...)
#define __xthe_whos__(...)
#define __xthe___declspec(...)
#define __xthe___attribute__(...)

// base_list 基类清单
#define __xbase__
#define __xbase_name__(...)
#define __xbase_tmpl__(...)
#define __xbase_spec__(...)
#define __xbase_pubb__(...)                 , __VA_ARGS__
#define __xbase_prob__(...)                 , __VA_ARGS__
#define __xbase_prib__(...)                 , __VA_ARGS__
#define __xbase_pubf__(...)
#define __xbase_prof__(...)
#define __xbase_prif__(...)
#define __xbase_pubf_no_mut__(...)
#define __xbase_prof_no_mut__(...)
#define __xbase_prif_no_mut__(...)
#define __xbase_pubc__(...)
#define __xbase_proc__(...)
#define __xbase_pric__(...)
#define __xbase_asso__(...)
#define __xbase_whos__(...)
#define __xbase___declspec(...)
#define __xbase___attribute__(...)

// member_list 所有成员清单
#define __xplaced__
#define __xplaced_name__(...)               __VA_ARGS__
#define __xplaced_tmpl__(NAME,...)          NAME<__VA_ARGS__>
#define __xplaced_spec__(NAME,...)          NAME<__VA_ARGS__>
#define __xplaced_pubb__(...)               , __VA_ARGS__
#define __xplaced_prob__(...)               , __VA_ARGS__
#define __xplaced_prib__(...)               , __VA_ARGS__
#define __xplaced_pubf__(...)
#define __xplaced_prof__(...)
#define __xplaced_prif__(...)
#define __xplaced_pubf_no_mut__(...)
#define __xplaced_prof_no_mut__(...)
#define __xplaced_prif_no_mut__(...)
#define __xplaced_pubc__(...)
#define __xplaced_proc__(...)
#define __xplaced_pric__(...)
#define __xplaced_asso__(...)
#define __xplaced_whos__(...)
#define __xplaced___declspec(...)
#define __xplaced___attribute__(...)

// 字段
#define __xfield__
#define __xfield_name__(...)
#define __xfield_tmpl__(...)
#define __xfield_spec__(...)
#define __xfield_pubb__(...)
#define __xfield_prob__(...)
#define __xfield_prib__(...)
#define __xfield_pubf__(NAME,...)           public:     mutable __xstruct_repeat<__VA_ARGS__> NAME;
#define __xfield_prof__(NAME,...)           protected:  mutable __xstruct_repeat<__VA_ARGS__> NAME;
#define __xfield_prif__(NAME,...)           private:    mutable __xstruct_repeat<__VA_ARGS__> NAME;
#define __xfield_pubf_no_mut__(NAME,...)    public:     __xstruct_repeat<__VA_ARGS__> NAME;
#define __xfield_prof_no_mut__(NAME,...)    protected:  __xstruct_repeat<__VA_ARGS__> NAME;
#define __xfield_prif_no_mut__(NAME,...)    private:    __xstruct_repeat<__VA_ARGS__> NAME;
#define __xfield_pubc__(NAME,BITS,...)      public:     mutable __xstruct_repeat<__VA_ARGS__> NAME    : BITS;
#define __xfield_proc__(NAME,BITS,...)      protected:  mutable __xstruct_repeat<__VA_ARGS__> NAME    : BITS;
#define __xfield_pric__(NAME,BITS,...)      private:    mutable __xstruct_repeat<__VA_ARGS__> NAME    : BITS;

#define __xfield_asso__(...)
#define __xfield_whos__(...)                                                                                        \
public:                                                                                                             \
    static constexpr ::mixc::macro_xstruct::inc::classify_t which_series_struct() { return __VA_ARGS__; }

#define __xfield___declspec(...)
#define __xfield___attribute__(...)

// 非基类成员字段指针
#define __xmlist__
#define __xmlist_name__(...)
#define __xmlist_tmpl__(...)
#define __xmlist_spec__(...)
#define __xmlist_pubb__(...)
#define __xmlist_prob__(...)
#define __xmlist_prib__(...)
#define __xmlist_pubf__(NAME,...)           , & the_t::NAME
#define __xmlist_prof__(NAME,...)           , & the_t::NAME
#define __xmlist_prif__(NAME,...)           , & the_t::NAME
#define __xmlist_pubf_no_mut__(NAME,...)    , & the_t::NAME
#define __xmlist_prof_no_mut__(NAME,...)    , & the_t::NAME
#define __xmlist_prif_no_mut__(NAME,...)    , & the_t::NAME
#define __xmlist_pubc__(NAME,...)           , & the_t::__bf_ ## NAME
#define __xmlist_proc__(NAME,...)           , & the_t::__bf_ ## NAME
#define __xmlist_pric__(NAME,...)           , & the_t::__bf_ ## NAME
#define __xmlist_asso__(...)                , & __xstruct_fake<__VA_ARGS__>::item
#define __xmlist_whos__(...)
#define __xmlist___declspec(...)
#define __xmlist___attribute__(...)

#define __xtype__
#define __xtype_name__(...)                 #__VA_ARGS__
#define __xtype_tmpl__(NAME,...)            #NAME
#define __xtype_spec__(NAME,...)            #NAME
#define __xtype_pubb__(...)
#define __xtype_prob__(...)
#define __xtype_prib__(...)
#define __xtype_pubf__(...)
#define __xtype_prof__(...)
#define __xtype_prif__(...)
#define __xtype_pubf_no_mut__(...)
#define __xtype_prof_no_mut__(...)
#define __xtype_prif_no_mut__(...)
#define __xtype_pubc__(...)
#define __xtype_proc__(...)
#define __xtype_pric__(...)
#define __xtype_asso__(...)
#define __xtype_whos__(...)
#define __xtype___declspec(...)
#define __xtype___attribute__(...)

#define __xtype_u__
#define __xtype_u_name__(...)                 u"" #__VA_ARGS__
#define __xtype_u_tmpl__(NAME,...)            u"" #NAME
#define __xtype_u_spec__(NAME,...)            u"" #NAME
#define __xtype_u_pubb__(...)
#define __xtype_u_prob__(...)
#define __xtype_u_prib__(...)
#define __xtype_u_pubf__(...)
#define __xtype_u_prof__(...)
#define __xtype_u_prif__(...)
#define __xtype_u_pubf_no_mut__(...)
#define __xtype_u_prof_no_mut__(...)
#define __xtype_u_prif_no_mut__(...)
#define __xtype_u_pubc__(...)
#define __xtype_u_proc__(...)
#define __xtype_u_pric__(...)
#define __xtype_u_asso__(...)
#define __xtype_u_whos__(...)
#define __xtype_u___declspec(...)
#define __xtype_u___attribute__(...)

#define __xitem__
#define __xitem_name__(...)
#define __xitem_tmpl__(...)
#define __xitem_spec__(...)
#define __xitem_pubb__(...)
#define __xitem_prob__(...)
#define __xitem_prib__(...)
#define __xitem_pubf__(NAME,...)            #NAME,
#define __xitem_prof__(NAME,...)            #NAME,
#define __xitem_prif__(NAME,...)            #NAME,
#define __xitem_pubf_no_mut__(NAME,...)     #NAME,
#define __xitem_prof_no_mut__(NAME,...)     #NAME,
#define __xitem_prif_no_mut__(NAME,...)     #NAME,
#define __xitem_pubc__(NAME,...)            #NAME,
#define __xitem_proc__(NAME,...)            #NAME,
#define __xitem_pric__(NAME,...)            #NAME,
#define __xitem_asso__(...)
#define __xitem_whos__(...)
#define __xitem___declspec(...)
#define __xitem___attribute__(...)

#define __xitem_u__
#define __xitem_u_name__(...)
#define __xitem_u_tmpl__(...)
#define __xitem_u_spec__(...)
#define __xitem_u_pubb__(...)
#define __xitem_u_prob__(...)
#define __xitem_u_prib__(...)
#define __xitem_u_pubf__(NAME,...)          u"" #NAME,
#define __xitem_u_prof__(NAME,...)          u"" #NAME,
#define __xitem_u_prif__(NAME,...)          u"" #NAME,
#define __xitem_u_pubf_no_mut__(NAME,...)   u"" #NAME,
#define __xitem_u_prof_no_mut__(NAME,...)   u"" #NAME,
#define __xitem_u_prif_no_mut__(NAME,...)   u"" #NAME,
#define __xitem_u_pubc__(NAME,...)          u"" #NAME,
#define __xitem_u_proc__(NAME,...)          u"" #NAME,
#define __xitem_u_pric__(NAME,...)          u"" #NAME,
#define __xitem_u_asso__(...)
#define __xitem_u_whos__(...)
#define __xitem_u___declspec(...)
#define __xitem_u___attribute__(...)

// TODO:
// 多个 [[no_unique_address]] 标记的成员变量并不会共用一个起始地址
// 所以需要优化位域反射机制
#define __xfield_helper(NAME,...)                                                                                   \
private:                                                                                                            \
    /*如果使用 struct 则需要 xstruct 结构，使用 union 会当作 int 之类的普通类型对待*/                               \
    union __bit_field_ ## NAME{                                                                                     \
        __xstruct_rv<__VA_ARGS__> get(the_t const & self) const {                                                   \
            return self.NAME;                                                                                       \
        }                                                                                                           \
                                                                                                                    \
        void set(the_t & self, __xstruct_rv<__VA_ARGS__> const & value){                                            \
            self.NAME = value;                                                                                      \
        }                                                                                                           \
    };                                                                                                              \
                                                                                                                    \
    static inline __bit_field_ ## NAME __bf_ ## NAME;

// 注意：
// 不能将 __xfield_helper() 直接放到 __xfield_pubc__、__xfield_proc__、__xfield_pric__ 的末尾
// __xbit_field_ 是为了解决 clang-11 不支持优化插在中间的 [[no_unique_address]] 
// struct __no_unique_address_test{
//     char field0 : 1;
//     [[no_unique_address]] struct{} foo0;
//     char field1 : 1;
//     [[no_unique_address]] struct{} foo1;
//     char __dummy2;
// };


#define __xbit_field__
#define __xbit_field_name__(...)
#define __xbit_field_tmpl__(...)
#define __xbit_field_spec__(...)
#define __xbit_field_pubb__(...)
#define __xbit_field_prob__(...)
#define __xbit_field_prib__(...)
#define __xbit_field_pubf__(...)
#define __xbit_field_prof__(...)
#define __xbit_field_prif__(...)
#define __xbit_field_pubf_no_mut__(...)
#define __xbit_field_prof_no_mut__(...)
#define __xbit_field_prif_no_mut__(...)
#define __xbit_field_pubc__(NAME,BITS,...)       __xfield_helper(NAME,__VA_ARGS__)
#define __xbit_field_proc__(NAME,BITS,...)       __xfield_helper(NAME,__VA_ARGS__)
#define __xbit_field_pric__(NAME,BITS,...)       __xfield_helper(NAME,__VA_ARGS__)
#define __xbit_field_asso__(...)
#define __xbit_field_whos__(...)
#define __xbit_field___declspec(...)
#define __xbit_field___attribute__(...)



#define xstruct(...)                                                            \
struct __xlist__(__xstruct_, __VA_ARGS__)                                       \
       __xlist3__(__xexpand_first_, __xexpand_first_, __xexpand_, __VA_ARGS__) {\
    using the_t = __xlist__(__xthe_, __VA_ARGS__);                              \
    __xlist__(__xfield_, __VA_ARGS__)                                           \
    __xlist__(__xbit_field_, __VA_ARGS__)                                       \
                                                                                \
private:                                                                        \
    static constexpr auto __my_name =                                           \
        __xlist__(__xtype_, __VA_ARGS__);                                       \
                                                                                \
    static constexpr auto __my_name_u =                                         \
        __xlist__(__xtype_u_, __VA_ARGS__);                                     \
                                                                                \
    static constexpr asciis __my_field_name[] =                                 \
        { __xlist__(__xitem_, __VA_ARGS__)  ""/*dummy*/ };                      \
                                                                                \
    static constexpr words __my_field_name_u[] =                                \
        { __xlist__(__xitem_u_, __VA_ARGS__)  u""/*dummy*/ };                   \
                                                                                \
    template<class, class>                                                      \
    friend struct ::mixc::macro_xtypeid::__typeid;                              \
                                                                                \
    template<class>                                                             \
    friend struct ::mixc::gc_private_gc_tuple::gc_tuple;                        \
public:                                                                         \
    xmark_is_xstruct();                                                         \
                                                                                \
    template<class __child_t>                                                   \
    using __fields_hubx =                                                       \
        typename decltype(::__fields_filter<                                    \
            __child_t __xlist__(__xbase_, __VA_ARGS__)                          \
        >(__xstruct_tl<>{}))::type;                                             \
                                                                                \
    using base_list = __xstruct_bl<                                             \
        void/*ignore*/ __xlist__(__xbase_, __VA_ARGS__)                         \
    >;                                                                          \
    using member_list_partial = __xstruct_mlp<                                  \
        nullptr/*ignore*/ __xlist__(__xmlist_, __VA_ARGS__)                     \
    >;                                                                          \
    /* __xstruct_dfc 内部会获取基类 member_list_partial */                      \
    /* 并与当前 member_list_partial 合并 */                                     \
    using member_list = __xstruct_dfc<                                          \
        __xlist__(__xplaced_, __VA_ARGS__)                                      \
    >;

#define $               };

#endif
